package com.drakulo.games.ais.ui.component;

import java.math.BigDecimal;
import java.util.List;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.tiled.TiledMap;

import com.drakulo.games.ais.core.Colony;
import com.drakulo.games.ais.core.GameData;
import com.drakulo.games.ais.core.Settings;
import com.drakulo.games.ais.core.building.Building;
import com.drakulo.games.ais.ui.TileHelper;
import com.drakulo.games.ais.ui.state.SectorState;

/**
 * This component displays a minimap of the current TiledMap. The player can
 * interract with it an jump to a specific position by clicking on it
 * 
 * @author Drakulo
 * 
 */
public class Minimap extends UIComponent {
	/** The minimap Width */
	public static final BigDecimal WIDTH = BigDecimal.valueOf(150);
	/** The minimap height */
	public static final BigDecimal HEIGHT = BigDecimal.valueOf(150);
	/** */
	private BigDecimal x;
	/** */
	private BigDecimal y;
	/** The tiledmap width */
	private BigDecimal mapWidth;
	/** The tiledmap height */
	private BigDecimal mapHeight;
	/** The minimap zone for mouse detection */
	private Rectangle miniMapZone;

	public Minimap(int x, int y) {
		this.x = BigDecimal.valueOf(x);
		this.y = BigDecimal.valueOf(y);

		this.miniMapZone = new Rectangle(this.x.intValue(), this.y.intValue(),
				WIDTH.intValue() + 1, HEIGHT.intValue() + 1);

		TiledMap tiledMap = GameData.getCurrentMap();
		final BigDecimal tileWidth = BigDecimal
				.valueOf(tiledMap.getTileWidth());
		final BigDecimal tileHeight = BigDecimal.valueOf(tiledMap
				.getTileHeight());
		final BigDecimal tileNumberX = BigDecimal.valueOf(tiledMap.getWidth());
		final BigDecimal tileNumberY = BigDecimal.valueOf(tiledMap.getHeight());

		this.mapWidth = tileWidth.multiply(tileNumberX);
		this.mapHeight = tileHeight.multiply(tileNumberY);
	}

	public void render(Graphics g) throws SlickException {
		TiledMap map = GameData.getCurrentMap();

		BigDecimal scaleX = WIDTH.divide(this.mapWidth);
		BigDecimal scaleY = HEIGHT.divide(this.mapHeight);

		Color lastColor = g.getColor();

		g.scale(scaleX.floatValue(), scaleY.floatValue());

		BigDecimal scaledX = this.x.multiply(this.mapWidth).divide(WIDTH, 0);
		BigDecimal scaledY = this.y.multiply(this.mapHeight).divide(HEIGHT, 0);

		map.render(scaledX.intValue(), scaledY.intValue(),
				TileHelper.DECO_LAYER);

		// Rendering of buildings representations (squares of the caregory
		// color)
		List<Building> buildings = GameData.getSelectedColony().getBuildings();
		int buildingX;
		int buildingY;
		int tileSize = Settings.TILE_SIZE;
		for (Building b : buildings) {
			buildingX = b.getX() * tileSize;
			buildingY = b.getY() * tileSize;
			Rectangle rect = new Rectangle(scaledX.intValue() + buildingX,
					scaledY.intValue() + buildingY, tileSize, tileSize);
			g.setColor(b.getCategory().getColor());
			g.fill(rect);
		}

		g.setColor(Color.white);
		Colony c = GameData.getSelectedColony();
		BigDecimal vpX = BigDecimal.valueOf(c.getViewportX()).negate()
				.add(scaledX);
		BigDecimal vpY = BigDecimal.valueOf(c.getViewportY()).negate()
				.add(scaledY);
		final int width = SectorState.VIEWPORT_WIDTH;
		final int height = SectorState.VIEWPORT_HEIGHT;

		g.draw(new Rectangle(vpX.intValue(), vpY.intValue() + SectorState.TOP_BAR_HEIGHT, width, height));

		g.scale(1 / scaleX.floatValue(), 1 / scaleY.floatValue());
		g.setColor(lastColor);
	}

	public void update(Input input) throws SlickException {
		int mouseX = input.getMouseX();
		int mouseY = input.getMouseY();
		boolean leftClick = input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON);

		if (leftClick && this.miniMapZone.contains(mouseX, mouseY)) {

			BigDecimal mX = BigDecimal.valueOf(mouseX).subtract(this.x)
					.multiply(this.mapWidth).divide(WIDTH, 0);
			BigDecimal mY = BigDecimal.valueOf(mouseY).subtract(this.y)
					.multiply(this.mapHeight).divide(HEIGHT, 0);

			mX = mX.subtract(BigDecimal.valueOf(Settings.WIDTH / 2));
			mY = mY.subtract(BigDecimal.valueOf(Settings.HEIGHT / 2));

			Colony c = GameData.getSelectedColony();
			c.setViewportX(-mX.intValue());
			c.setViewportY(-mY.intValue());
		}
	}

	public int getWidth() {
		return WIDTH.intValue();
	}

	public int getHeight() {
		return HEIGHT.intValue();
	}

	public int getX() {
		return this.x.intValue();
	}

	public int getY() {
		return this.y.intValue();
	}
}
